(function(host){

host = host || window;
var mvc = host.mvc || {};


function CreateDragableLayer(el, className){
	var conf = {
		el: el,
		className: className,
		type: 'dragable',
		create_rule: 1
	}
	var layer = mvc.layer.rect(conf);
	layer.addView({ type: 'move' });
	layer.addView({ type: 'resize' });
	return layer;
}

function CreateModelSnap(model){
	var snap = null;
	var MODEL = model || null;
	var R = {
		attach: function(m){
			MODEL = m;
			this.snap();
		},
		snap: function(){
			if(!MODEL) return this;
			snap = MODEL.output();
			return this;
		},
		output: function(fn){
			var args = Array.prototype.slice.call(arguments, 1);
			return fn.apply(this, args);
		},
		position: function(offset){
			return {
				left: snap.left + offset.x,
				top: snap.top + offset.y
			}
		},
		size: function(offset){
			return {
				width: Math.max(0, snap.width + offset.x),
				height: Math.max(0, snap.height + offset.y)
			}
		}
	};
	R.snap();
	return R;
}

mvc.CreateDragableLayer = CreateDragableLayer;
mvc.CreateModelSnap = CreateModelSnap;

function MVCDrager(el){
	el = util.$(el) || document;

	var startPos, state = 0, target = null;
	var mousedown, mousemove, mouseup;
	var enable = true;
	var result = {
		scale: 1,
		$state: function(e){
			return -1;
		},
		onbegin: function(pos){},
		onmove: function(offset){},
		onend: function(offset){},
		dispose: function(){
			util.removeEvent(el, 'mousedown', mousedown);
			util.removeEvent(el, 'mousemove', mousemove);
			util.removeEvent(el, 'mouseup', mouseup);
		},
		enable: function(){
			enable = true;
		},
		disable: function(){
			enable = false;
		}
	};
	util.addEvent(el, 'mousedown', mousedown = function(e){
		if(!enable) return;
		if('button' in e && e.button != 0){
			return;
		}
		if(result.$state(e) != 0){
			return;
		}
		e.stopPropagation();
		e.preventDefault();
		state = 1;
		startPos = util.getSingleEventPostion(e);
		result.onbegin(startPos);
	});

	util.addEvent(document, 'mousemove', mousemove = function(e){
		if(!enable) return;
		if(state != 1){
			return;
		}

		e.stopPropagation();
		e.preventDefault();

		var pos = util.getSingleEventPostion(e);
		var offset = {
			x: ((pos[0] - startPos[0]) / result.scale) >> 0,
			y: ((pos[1] - startPos[1]) / result.scale) >> 0
		};
		result.onmove(offset);
	});

	util.addEvent(document, 'mouseup', mousemove = function(e){
		if(!enable) return;

		if(state == 1){
			var pos = util.getSingleEventPostion(e);
			var offset = {
				x: ((pos[0] - startPos[0]) / result.scale) >> 0,
				y: ((pos[1] - startPos[1]) / result.scale) >> 0
			};
			result.onend(offset);
			e.stopPropagation();
			e.preventDefault();
			state = 0;
			// target = null;
		}
	});
	return result;
}
mvc.dragger = function(el){ return MVCDrager(el); };


})(window)